﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace GeoParser
{
	public sealed class ImmutableAttribute : Attribute
	{
	}

	/// <summary>
	/// Represents a route consisting of a number waypoints in an order.
	/// </summary>
	[Immutable]
	public class Route
	{
		private readonly List<Waypoint> m_Waypoints = new List<Waypoint>();

		public string Name { get; set; }
		public string Description { get; set; }
		public Guid Number { get; set; }

		public Route()
		{
			Number = Guid.NewGuid();
		}

		public Route(IEnumerable<Waypoint> waypoints)
			: this()
		{
			if (waypoints != null)
				m_Waypoints.AddRange(waypoints);
		}

		public Route(params Waypoint[] waypoints)
			: this()
		{
			if (waypoints != null)
				m_Waypoints.AddRange(waypoints);
		}

		public void Add(IEnumerable<Waypoint> waypoints)
		{
			if (waypoints != null)
				m_Waypoints.AddRange(waypoints);
		}

		public void Add(params Waypoint[] waypoints)
		{
			if (waypoints != null)
				m_Waypoints.AddRange(waypoints);
		}

		public override string ToString()
		{
			return Name;
		}

		public XElement ToXElement(XNamespace @namespace)
		{
			if (@namespace == null)
				@namespace = XNamespace.None;
	
			var routeElement = new XElement(@namespace + "rte",
				new XElement(@namespace + "name", Name),
				new XElement(@namespace + "cmt", Description),
				new XElement(@namespace + "number", Number));

			foreach (Waypoint waypoint in m_Waypoints)
			{
				routeElement.Add(new XElement(@namespace + "rtept",
					new XAttribute("lat", waypoint.Latitude),
					new XAttribute("lon", waypoint.Longitude),
					new XElement(@namespace + "name", waypoint.Name),
					new XElement(@namespace + "desc", waypoint.Description)));
			}

			return routeElement;
		}

		public Distance Length
		{
			get
			{
				return Distance.Length(m_Waypoints.Cast<GeoPoint>());
			}
		}
	}
}